﻿using System;
using System.IO;
using System.Xml.XPath;
using System.Xml;

namespace TfsSpam.Utilities
{
    /// <summary>
    /// The TfsEventParser class provides simple utility methods
    /// for getting information out of the XML data TFS sends for
    /// event notifications.
    /// </summary>
    public static class TfsEventParser
    {
        #region -- Public class constants
        /// <summary>
        /// The value returned if a changeset id can't be determined
        /// from the information received in a CheckinEvent notification.
        /// </summary>
        public const int InvalidChangesetId = -1;
        #endregion

        #region -- TFS event parsing support
        /// <summary>
        /// Given the XML string provided in a TFS CheckinEvent notification, this
        /// method retrieves the id of the associated Changeset.
        /// </summary>
        /// <param name="notifyXml">The string containing the XML data received by the TFS event handler.</param>
        /// <returns>
        /// The changeset id read from <paramref name="notifyXml"/> or <see cref="InvalidChangesetId"/>
        /// if the changeset id can't be determined.
        /// </returns>
        /// <exception cref="ArgumentNullException">Thrown if <paramref name="notifyXml"/> is <c>null</c> or empty.</exception>
        /// <exception cref="XmlException">Thrown if the contents of <paramref name="notifyXml"/> can't be parsed as XML.</exception>
        public static int GetChangesetId( string notifyXml )
        {
            if ( string.IsNullOrEmpty( notifyXml ) )
            {
                // We need a string that contains some data.
                throw new ArgumentNullException( "notifyXml" );
            }

            using ( StringReader stringReader = new StringReader( notifyXml ) )
            {
                XPathDocument notifyDocument = new XPathDocument( stringReader );
                XPathNavigator navigator = notifyDocument.CreateNavigator();
                XPathNavigator changesetNode = navigator.SelectSingleNode( "/CheckinEvent/Number" );

                // Does the XML document contain the changeset id node?
                if ( changesetNode != null )
                {
                    int changesetId = InvalidChangesetId;

                    // Yes, try to get the value of it.
                    if ( int.TryParse( changesetNode.Value, System.Globalization.NumberStyles.Any, System.Globalization.CultureInfo.InvariantCulture, out changesetId ) )
                    {
                        return changesetId;
                    }
                }
            }

            return InvalidChangesetId;
        }
        #endregion
    }
}
